using System;
using System.Collections.Generic;
using System.Text;

namespace OracleInternal.I18N
{
	[Serializable]
	internal class TLBConvShift : TLBConv12Byte
	{
		private delegate int ConvertByteToCharsShiftDelegate<T>(byte[] bytes, int byteOffsets, int byteCounts, T[] chars, int charOffset, ref int charCount, ref bool shiftIn, bool bUseReplacementChar);

		private const byte SHIFT_OUT = 14;

		private const byte SHIFT_IN = 15;

		public override int MinBytesPerChar => 2;

		public override int MaxBytesPerChar => 3;

		internal override bool IsShitCharset()
		{
			return true;
		}

		public TLBConvShift()
		{
			m_groupId = 7;
		}

		private int GetCharsLengthShiftImpl(byte[] bytes, int offset, int count, ref bool shiftIn, ref int bytesCounted)
		{
			byte b = 15;
			int num = offset;
			int num2 = offset + count;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			int num3 = 0;
			while (num < num2)
			{
				if (bytes[num] == 15)
				{
					b = 15;
					shiftIn = true;
					num++;
					continue;
				}
				if (bytes[num] == 14)
				{
					b = 14;
					shiftIn = false;
					num++;
					continue;
				}
				if ((b == 15) & shiftIn)
				{
					int srcChar = bytes[num] & 0xFF;
					num3 = (((ToUnicode(srcChar, ccb: true) & 0xFFFFFFFFu) <= 65535) ? (num3 + 1) : (num3 + 2));
					num++;
					continue;
				}
				if (num < num2 - 1)
				{
					int srcChar = ((bytes[num] << 8) & 0xFF00) | (bytes[num + 1] & 0xFF);
					num3 = (((ToUnicode(srcChar, ccb: true) & 0xFFFFFFFFu) <= 65535) ? (num3 + 1) : (num3 + 2));
					num += 2;
					continue;
				}
				bytesCounted = num - offset;
				break;
			}
			bytesCounted = num - offset;
			return num3;
		}

		public override int GetCharsLength(byte[] bytes, int byteOffset, int byteCount)
		{
			int bytesCounted = 0;
			bool shiftIn = true;
			return GetCharsLengthShiftImpl(bytes, byteOffset, byteCount, ref shiftIn, ref bytesCounted);
		}

		private int GetBytesOffsetShiftImpl(byte[] bytes, int offset, int count, ref int charCount, ref bool shiftIn)
		{
			byte b = 15;
			int num = offset;
			int num2 = offset + count;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			int num3 = 0;
			while (num < num2 && num3 < charCount)
			{
				if (bytes[num] == 15)
				{
					b = 15;
					shiftIn = true;
					num++;
					continue;
				}
				if (bytes[num] == 14)
				{
					b = 14;
					shiftIn = false;
					num++;
					continue;
				}
				int srcChar;
				if ((b == 15) & shiftIn)
				{
					srcChar = bytes[num] & 0xFF;
					num3 = (((ToUnicode(srcChar, ccb: true) & 0xFFFFFFFFu) <= 65535) ? (num3 + 1) : (num3 + 2));
					num++;
					continue;
				}
				if (num >= num2 - 1)
				{
					break;
				}
				srcChar = ((bytes[num] << 8) & 0xFF00) | (bytes[num + 1] & 0xFF);
				num3 = (((ToUnicode(srcChar, ccb: true) & 0xFFFFFFFFu) <= 65535) ? (num3 + 1) : (num3 + 2));
				num += 2;
			}
			charCount = num3;
			return num - offset;
		}

		public override int GetBytesOffset(byte[] bytes, int byteOffset, int byteCount, int charCount)
		{
			int charCount2 = charCount;
			bool shiftIn = true;
			return GetBytesOffsetShiftImpl(bytes, byteOffset, byteCount, ref charCount2, ref shiftIn);
		}

		public override int GetCharsLength(ArraySegment<byte> bytes, int bytesOffset, int bytesCount)
		{
			int bytesCounted = 0;
			bool shiftIn = true;
			return GetCharsLengthShiftImpl(bytes.Array, bytes.Offset + bytesOffset, bytesCount, ref shiftIn, ref bytesCounted);
		}

		public override int GetCharsLength(IList<ArraySegment<byte>> bytes, int bytesOffset, int bytesCount)
		{
			int num = 0;
			int bytesCounted = 0;
			int num2 = 0;
			int continuationOffset = 0;
			byte[] array = null;
			int num3 = 0;
			bool shiftIn = true;
			int idx = 0;
			int offSet = bytes[0].Offset;
			bool flag = false;
			if (bytesOffset > 0)
			{
				UTF16ConvUtility.GetSegementIndices(bytes, bytesOffset, ref idx, ref offSet);
			}
			for (int i = idx; i < bytes.Count; i++)
			{
				if (flag)
				{
					break;
				}
				int num4 = bytes[i].Offset + continuationOffset;
				int num5 = bytes[i].Count - continuationOffset;
				if (i == idx)
				{
					num4 = offSet + continuationOffset;
					num5 = bytes[i].Count - (offSet - bytes[i].Offset) - continuationOffset;
				}
				if (bytesCount - num2 <= num5)
				{
					num5 = bytesCount - num2;
					flag = true;
				}
				int charsLengthShiftImpl = GetCharsLengthShiftImpl(bytes[i].Array, num4, num5, ref shiftIn, ref bytesCounted);
				num += charsLengthShiftImpl;
				num2 += bytesCounted;
				if (bytesCounted < num5 && !flag && i < bytes.Count - 1)
				{
					if (array == null)
					{
						array = new byte[2];
					}
					_ = bytes[i + 1].Array;
					int num6 = num4 + bytesCounted;
					_ = bytes[i].Array[num6];
					UTF16ConvUtility.GetRemainingBytes(2, bytes[i].Array, num6, 1, bytes, ref i, ref continuationOffset, array);
					num3 = 2;
					charsLengthShiftImpl = GetCharsLengthShiftImpl(array, 0, num3, ref shiftIn, ref bytesCounted);
					num += charsLengthShiftImpl;
					num2 += bytesCounted;
				}
				else
				{
					continuationOffset = 0;
				}
			}
			return num;
		}

		private int ConvertBytesToCharsImpl(byte[] bytes, int offset, int count, char[] chars, int charOffset, ref int charCount, ref bool shiftIn, bool ccb)
		{
			byte b = 15;
			int num = offset;
			if (num < 0)
			{
				num = 0;
			}
			int num2 = num + count;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			int num3 = charOffset;
			if (num3 < 0)
			{
				num3 = 0;
			}
			int num4 = num3 + charCount;
			if (num4 > chars.Length)
			{
				num4 = chars.Length;
			}
			while (num < num2 && num3 < num4)
			{
				if (bytes[num] == 15)
				{
					b = 15;
					shiftIn = true;
					num++;
					continue;
				}
				if (bytes[num] == 14)
				{
					b = 14;
					shiftIn = false;
					num++;
					continue;
				}
				if ((b == 15) & shiftIn)
				{
					int srcChar = bytes[num] & 0xFF;
					int num5 = ToUnicode(srcChar, ccb);
					if ((num5 & 0xFFFFFFFFu) > 65535)
					{
						if (num3 >= num4)
						{
							break;
						}
						chars[num3++] = (char)(num5 >> 16);
						chars[num3++] = (char)((uint)num5 & 0xFFFFu);
					}
					else
					{
						chars[num3++] = (char)num5;
					}
					num++;
					continue;
				}
				if (num < num2 - 1)
				{
					int srcChar = ((bytes[num] << 8) & 0xFF00) | (bytes[num + 1] & 0xFF);
					int num6 = ToUnicode(srcChar, ccb);
					if ((num6 & 0xFFFFFFFFu) > 65535)
					{
						if (num3 >= num4)
						{
							break;
						}
						chars[num3++] = (char)(num6 >> 16);
						chars[num3++] = (char)((uint)num6 & 0xFFFFu);
					}
					else
					{
						chars[num3++] = (char)num6;
					}
					num += 2;
					continue;
				}
				if (ccb)
				{
					break;
				}
				throw new DecoderFallbackException("Failed to convert bytes to Unicode");
			}
			charCount = num3 - charOffset;
			return num - offset;
		}

		private int ConvertBytesToUTF16Impl(byte[] bytes, int offset, int count, byte[] utfbytes, int utfOffset, ref int utfCount, ref bool shiftIn, bool ccb)
		{
			int num = offset;
			if (num < 0)
			{
				num = 0;
			}
			int num2 = num + count;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			int num3 = utfOffset;
			if (num3 < 0)
			{
				num3 = 0;
			}
			int num4 = num3 + utfCount;
			if (num4 > utfbytes.Length)
			{
				num4 = utfbytes.Length;
			}
			byte b = 15;
			while (num < num2 && num3 + 1 < num4)
			{
				if (bytes[num] == 15)
				{
					b = 15;
					shiftIn = true;
					num++;
					continue;
				}
				if (bytes[num] == 14)
				{
					b = 14;
					shiftIn = false;
					num++;
					continue;
				}
				if ((b == 15) & shiftIn)
				{
					int srcChar = bytes[num] & 0xFF;
					int num5 = ToUnicode(srcChar, ccb);
					if ((num5 & 0xFFFFFFFFu) > 65535)
					{
						if (num3 + 3 >= num4)
						{
							break;
						}
						char[] array = new char[2]
						{
							(char)(num5 >> 16),
							(char)((uint)num5 & 0xFFFFu)
						};
						utfbytes[num3++] = (byte)(array[0] & 0xFFu);
						utfbytes[num3++] = (byte)((int)array[0] >> 8);
						utfbytes[num3++] = (byte)(array[1] & 0xFFu);
						utfbytes[num3++] = (byte)((int)array[1] >> 8);
					}
					else
					{
						utfbytes[num3++] = (byte)((ushort)num5 & 0xFFu);
						utfbytes[num3++] = (byte)((ushort)num5 >> 8);
					}
					num++;
					continue;
				}
				if (num < num2 - 1)
				{
					int srcChar = ((bytes[num] << 8) & 0xFF00) | (bytes[num + 1] & 0xFF);
					int num6 = ToUnicode(srcChar, ccb);
					if ((num6 & 0xFFFFFFFFu) > 65535)
					{
						if (num3 + 3 >= num4)
						{
							break;
						}
						char[] array2 = new char[2]
						{
							(char)(num6 >> 16),
							(char)((uint)num6 & 0xFFFFu)
						};
						utfbytes[num3++] = (byte)(array2[0] & 0xFFu);
						utfbytes[num3++] = (byte)((int)array2[0] >> 8);
						utfbytes[num3++] = (byte)(array2[1] & 0xFFu);
						utfbytes[num3++] = (byte)((int)array2[1] >> 8);
					}
					else
					{
						utfbytes[num3++] = (byte)((ushort)num6 & 0xFFu);
						utfbytes[num3++] = (byte)((ushort)num6 >> 8);
					}
					num += 2;
					continue;
				}
				if (ccb)
				{
					break;
				}
				throw new DecoderFallbackException("Failed to convert bytes to Unicode");
			}
			utfCount = num3 - utfOffset;
			return num - offset;
		}

		public override int ConvertBytesToUTF16(byte[] bytes, int offset, int count, byte[] utfbytes, int utfOffset, ref int utfCount, bool ccb)
		{
			bool shiftIn = true;
			return ConvertBytesToUTF16Impl(bytes, offset, count, utfbytes, utfOffset, ref utfCount, ref shiftIn, ccb);
		}

		public override int ConvertBytesToChars(byte[] bytes, int offset, int count, char[] chars, int charOffset, ref int charCount, bool ccb)
		{
			bool shiftIn = true;
			return ConvertBytesToCharsImpl(bytes, offset, count, chars, charOffset, ref charCount, ref shiftIn, ccb);
		}

		internal override int ConvertBytesToChars(byte[] bytes, int offset, int count, char[] chars, int charOffset, ref int charCount, ref bool shiftIn, bool ccb)
		{
			return ConvertBytesToCharsImpl(bytes, offset, count, chars, charOffset, ref charCount, ref shiftIn, ccb);
		}

		private int ConvertByteArraySegListToCharsShiftImpl<T>(IList<ArraySegment<byte>> bytes, int bytesOffset, int bytesCount, T[] chars, int charOffset, ref int charCount, ref bool shiftState, bool bUseReplacementChar, ConvertByteToCharsShiftDelegate<T> t)
		{
			int num = charOffset;
			int charCount2 = charCount;
			int num2 = 0;
			int num3 = 0;
			int continuationOffset = 0;
			byte[] array = null;
			int num4 = 0;
			bool shiftIn = shiftState;
			int idx = 0;
			int offSet = bytes[0].Offset;
			bool flag = false;
			if (bytesOffset > 0)
			{
				UTF16ConvUtility.GetSegementIndices(bytes, bytesOffset, ref idx, ref offSet);
			}
			for (int i = idx; i < bytes.Count; i++)
			{
				if (flag)
				{
					break;
				}
				if (charCount2 <= 0)
				{
					break;
				}
				int num5 = bytes[i].Offset + continuationOffset;
				int num6 = bytes[i].Count - continuationOffset;
				if (i == idx)
				{
					num5 = offSet + continuationOffset;
					num6 = bytes[i].Count - (offSet - bytes[i].Offset) - continuationOffset;
				}
				if (bytesCount - num3 <= num6)
				{
					num6 = bytesCount - num3;
					flag = true;
				}
				int num7 = t(bytes[i].Array, num5, num6, chars, num, ref charCount2, ref shiftIn, bUseReplacementChar);
				num3 += num7;
				num += charCount2;
				num2 += charCount2;
				charCount2 = charCount - num2;
				if (charCount2 > 0 && num7 < num6 && !flag && i < bytes.Count - 1)
				{
					if (array == null)
					{
						array = new byte[2];
					}
					_ = bytes[i + 1].Array;
					int num8 = num5 + num7;
					_ = bytes[i].Array[num8];
					UTF16ConvUtility.GetRemainingBytes(2, bytes[i].Array, num8, 1, bytes, ref i, ref continuationOffset, array);
					num4 = 2;
					num7 = t(array, 0, num4, chars, num, ref charCount2, ref shiftIn, bUseReplacementChar);
					if (num7 == 0)
					{
						break;
					}
					num3 += num7;
					num += charCount2;
					num2 += charCount2;
					charCount2 = charCount - num2;
				}
				else
				{
					continuationOffset = 0;
				}
			}
			shiftState = shiftIn;
			charCount = num2;
			return num3;
		}

		public override int GetBytesOffset(IList<ArraySegment<byte>> bytes, int charCount)
		{
			int charCount2 = charCount;
			int num = 0;
			int num2 = 0;
			int continuationOffset = 0;
			byte[] array = null;
			int num3 = 0;
			bool shiftIn = true;
			for (int i = 0; i < bytes.Count; i++)
			{
				if (num >= charCount)
				{
					break;
				}
				int num4 = bytes[i].Offset + continuationOffset;
				int num5 = bytes[i].Count - continuationOffset;
				byte[] array2 = bytes[i].Array;
				int bytesOffsetShiftImpl = GetBytesOffsetShiftImpl(array2, num4, num5, ref charCount2, ref shiftIn);
				num2 += bytesOffsetShiftImpl;
				num += charCount2;
				charCount2 = charCount - num;
				if (charCount2 > 0 && bytesOffsetShiftImpl < num5 && i < bytes.Count - 1)
				{
					if (array == null)
					{
						array = new byte[2];
					}
					_ = bytes[i + 1].Array;
					int num6 = num4 + bytesOffsetShiftImpl;
					_ = array2[num6];
					UTF16ConvUtility.GetRemainingBytes(2, array2, num6, 1, bytes, ref i, ref continuationOffset, array);
					num3 = 2;
					bytesOffsetShiftImpl = GetBytesOffsetShiftImpl(array, 0, num3, ref charCount2, ref shiftIn);
					num2 += bytesOffsetShiftImpl;
					num += charCount2;
					charCount2 = charCount - num;
				}
				else
				{
					continuationOffset = 0;
				}
			}
			return num2;
		}

		public override int ConvertBytesToChars(IList<ArraySegment<byte>> bytes, int bytesOffset, int bytesCount, char[] chars, int charOffset, ref int charCount, bool bUseReplacementChar)
		{
			bool shiftState = true;
			return ConvertByteArraySegListToCharsShiftImpl(bytes, bytesOffset, bytesCount, chars, charOffset, ref charCount, ref shiftState, bUseReplacementChar, ConvertBytesToCharsImpl);
		}

		internal override int ConvertBytesToChars(IList<ArraySegment<byte>> bytes, int bytesOffset, int bytesCount, char[] chars, int charOffset, ref int charCount, ref bool shiftIn, bool bUseReplacementChar)
		{
			return ConvertByteArraySegListToCharsShiftImpl(bytes, bytesOffset, bytesCount, chars, charOffset, ref charCount, ref shiftIn, bUseReplacementChar, ConvertBytesToCharsImpl);
		}

		public override int GetBytesLength(char[] chars, int charOffset, int charCount)
		{
			int num = charOffset;
			int num2 = charOffset + charCount;
			int num3 = 0;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			char c = '\uffff';
			byte b = 15;
			for (int i = num; i < num2; i++)
			{
				if (chars[i] >= '\ud800' && chars[i] < '\udc00')
				{
					if (i + 1 >= num2 || chars[i + 1] < '\udc00' || chars[i + 1] > '\udfff')
					{
						if (b == 15)
						{
							b = 14;
							num3++;
						}
						num3 += 2;
						continue;
					}
					c = ToOracleCharacter(chars[i], chars[i + 1], ccb: true);
					i++;
				}
				else
				{
					c = ToOracleCharacter(chars[i], '\0', ccb: true);
				}
				if ((c & 0xFF00u) != 0)
				{
					if (b == 15)
					{
						b = 14;
						num3++;
					}
					num3 += 2;
				}
				else
				{
					if (b == 14)
					{
						b = 15;
						num3++;
					}
					num3++;
				}
			}
			if (b == 14)
			{
				b = 15;
				num3++;
			}
			return num3;
		}

		public override int GetBytesLength(string chars, int charOffset, int charCount)
		{
			int num = charOffset;
			int num2 = charOffset + charCount;
			int num3 = 0;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			char c = '\uffff';
			byte b = 15;
			for (int i = num; i < num2; i++)
			{
				if (chars[i] >= '\ud800' && chars[i] < '\udc00')
				{
					if (i + 1 >= num2 || chars[i + 1] < '\udc00' || chars[i + 1] > '\udfff')
					{
						if (b == 15)
						{
							b = 14;
							num3++;
						}
						num3 += 2;
						continue;
					}
					c = ToOracleCharacter(chars[i], chars[i + 1], ccb: true);
					i++;
				}
				else
				{
					c = ToOracleCharacter(chars[i], '\0', ccb: true);
				}
				if ((c & 0xFF00u) != 0)
				{
					if (b == 15)
					{
						b = 14;
						num3++;
					}
					num3 += 2;
				}
				else
				{
					if (b == 14)
					{
						b = 15;
						num3++;
					}
					num3++;
				}
			}
			if (b == 14)
			{
				b = 15;
				num3++;
			}
			return num3;
		}

		public override int GetBytesLength(byte[] utf16Bytes, int utf16BytesOffset, int utf16BytesCount)
		{
			int num = utf16BytesOffset;
			int num2 = utf16BytesOffset + utf16BytesCount;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > utf16Bytes.Length)
			{
				num2 = utf16Bytes.Length;
			}
			char c = '\uffff';
			byte b = 15;
			int num3 = 0;
			for (int i = num; i < num2 - 1; i += 2)
			{
				int num4 = (utf16Bytes[i + 1] << 8) | utf16Bytes[i];
				if (num4 >= 55296 && num4 < 56320)
				{
					if (i + 3 >= num2)
					{
						if (b == 15)
						{
							b = 14;
							num3++;
						}
						num3 += 2;
						continue;
					}
					int num5 = (utf16Bytes[i + 3] << 8) | utf16Bytes[i + 2];
					if (num5 >= 56320 && num5 <= 57343)
					{
						c = ToOracleCharacter((char)num4, (char)num5, ccb: true);
						i++;
					}
				}
				else
				{
					c = ToOracleCharacter((char)num4, '\0', ccb: true);
				}
				if ((c & 0xFF00u) != 0)
				{
					if (b == 15)
					{
						b = 14;
						num3++;
					}
					num3 += 2;
				}
				else
				{
					if (b == 14)
					{
						b = 15;
						num3++;
					}
					num3++;
				}
			}
			if (b == 14)
			{
				b = 15;
				num3++;
			}
			return num3;
		}

		public override int ConvertCharsToBytes(char[] chars, int chars_offset, int chars_count, byte[] bytes, int bytes_begin, ref int bytes_count, bool ccb)
		{
			int num = chars_offset;
			int num2 = chars_offset + chars_count;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			if (bytes_begin < 0)
			{
				bytes_begin = 0;
			}
			int num3 = bytes_begin + bytes_count;
			if (num3 > bytes.Length)
			{
				num3 = bytes.Length;
			}
			int num4 = bytes_begin;
			char c = '\uffff';
			byte b = 15;
			int i;
			for (i = num; i < num2 && num4 < num3; i++)
			{
				bool flag = false;
				if (chars[i] >= '\ud800' && chars[i] < '\udc00')
				{
					if (i + 1 >= num2 || chars[i + 1] < '\udc00' || chars[i + 1] > '\udfff')
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_BYTES"));
						}
						if (num4 + 1 >= num3)
						{
							break;
						}
						if (b == 15)
						{
							if (num4 + 2 >= num3)
							{
								break;
							}
							b = 14;
							bytes[num4++] = 14;
						}
						bytes[num4++] = (byte)((int)m_2ByteOraCharReplacement[0] >> 8);
						bytes[num4++] = (byte)m_2ByteOraCharReplacement[0];
						continue;
					}
					c = ToOracleCharacter(chars[i], chars[i + 1], ccb);
					flag = true;
					i++;
				}
				else
				{
					c = ToOracleCharacter(chars[i], '\0', ccb);
				}
				int num5;
				if ((num5 = c & 0xFF00) != 0)
				{
					if (num4 + 1 >= num3)
					{
						if (flag)
						{
							i--;
						}
						break;
					}
					if (b == 15)
					{
						if (num4 + 2 >= num3)
						{
							if (flag)
							{
								i--;
							}
							break;
						}
						b = 14;
						bytes[num4++] = 14;
					}
					bytes[num4++] = (byte)(num5 >> 8);
					bytes[num4++] = (byte)c;
					continue;
				}
				if (b == 14)
				{
					if (num4 + 1 >= num3)
					{
						if (flag)
						{
							i--;
						}
						break;
					}
					b = 15;
					bytes[num4++] = 15;
				}
				bytes[num4++] = (byte)c;
			}
			if (b == 14 && num4 < num3)
			{
				b = 15;
				bytes[num4++] = 15;
			}
			bytes_count = num4 - bytes_begin;
			return i - num;
		}

		public override int ConvertStringToBytes(string chars, int chars_offset, int chars_count, byte[] bytes, int bytes_begin, ref int bytes_count, bool ccb)
		{
			int num = chars_offset;
			int num2 = chars_offset + chars_count;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			if (bytes_begin < 0)
			{
				bytes_begin = 0;
			}
			int num3 = bytes_begin + bytes_count;
			if (num3 > bytes.Length)
			{
				num3 = bytes.Length;
			}
			int num4 = bytes_begin;
			char c = '\uffff';
			byte b = 15;
			int i;
			for (i = num; i < num2 && num4 < num3; i++)
			{
				bool flag = false;
				if (chars[i] >= '\ud800' && chars[i] < '\udc00')
				{
					if (i + 1 >= num2 || chars[i + 1] < '\udc00' || chars[i + 1] > '\udfff')
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_BYTES"));
						}
						if (num4 + 1 >= num3)
						{
							break;
						}
						if (b == 15)
						{
							if (num4 + 2 >= num3)
							{
								break;
							}
							b = 14;
							bytes[num4++] = 14;
						}
						bytes[num4++] = (byte)((int)m_2ByteOraCharReplacement[0] >> 8);
						bytes[num4++] = (byte)m_2ByteOraCharReplacement[0];
						continue;
					}
					c = ToOracleCharacter(chars[i], chars[i + 1], ccb);
					flag = true;
					i++;
				}
				else
				{
					c = ToOracleCharacter(chars[i], '\0', ccb);
				}
				int num5;
				if ((num5 = c & 0xFF00) != 0)
				{
					if (num4 + 1 >= num3)
					{
						if (flag)
						{
							i--;
						}
						break;
					}
					if (b == 15)
					{
						if (num4 + 2 >= num3)
						{
							if (flag)
							{
								i--;
							}
							break;
						}
						b = 14;
						bytes[num4++] = 14;
					}
					bytes[num4++] = (byte)(num5 >> 8);
					bytes[num4++] = (byte)c;
					continue;
				}
				if (b == 14)
				{
					if (num4 + 1 >= num3)
					{
						if (flag)
						{
							i--;
						}
						break;
					}
					b = 15;
					bytes[num4++] = 15;
				}
				bytes[num4++] = (byte)c;
			}
			if (b == 14 && num4 < num3)
			{
				b = 15;
				bytes[num4++] = 15;
			}
			bytes_count = num4 - bytes_begin;
			return i - num;
		}

		public override int ConvertUTF16ToBytes(byte[] utf16Bytes, int utf16BytesOffset, int utf16BytesCount, byte[] bytes, int byteOffset, ref int byteCount, bool ccb = true)
		{
			int num = utf16BytesOffset;
			int num2 = utf16BytesOffset + utf16BytesCount;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > utf16Bytes.Length)
			{
				num2 = utf16Bytes.Length;
			}
			if (byteOffset < 0)
			{
				byteOffset = 0;
			}
			int num3 = byteOffset + byteCount;
			if (num3 > bytes.Length)
			{
				num3 = bytes.Length;
			}
			char c = '\uffff';
			byte b = 15;
			int num4 = byteOffset;
			int i;
			for (i = num; i < num2 - 1 && num4 < num3; i += 2)
			{
				bool flag = false;
				int num5 = (utf16Bytes[i + 1] << 8) | utf16Bytes[i];
				if (num5 >= 55296 && num5 < 56320)
				{
					if (i + 3 >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_BYTES"));
						}
						if (num4 + 1 >= num3)
						{
							break;
						}
						if (b == 15)
						{
							if (num4 + 2 >= num3)
							{
								break;
							}
							b = 14;
							bytes[num4++] = 14;
						}
						bytes[num4++] = (byte)((int)m_2ByteOraCharReplacement[0] >> 8);
						bytes[num4++] = (byte)m_2ByteOraCharReplacement[0];
						continue;
					}
					int num6 = (utf16Bytes[i + 3] << 8) | utf16Bytes[i + 2];
					if (num6 >= 56320 && num6 <= 57343)
					{
						c = ToOracleCharacter((char)num5, (char)num6, ccb);
						flag = true;
						i += 2;
					}
				}
				else
				{
					c = ToOracleCharacter((char)num5, '\0', ccb);
				}
				int num7;
				if ((num7 = c & 0xFF00) != 0)
				{
					if (num4 + 1 >= num3)
					{
						if (flag)
						{
							i -= 2;
						}
						break;
					}
					if (b == 15)
					{
						if (num4 + 2 >= num3)
						{
							if (flag)
							{
								i -= 2;
							}
							break;
						}
						b = 14;
						bytes[num4++] = 14;
					}
					bytes[num4++] = (byte)(num7 >> 8);
					bytes[num4++] = (byte)c;
					continue;
				}
				if (b == 14)
				{
					if (num4 + 1 >= num3)
					{
						if (flag)
						{
							i -= 2;
						}
						break;
					}
					b = 15;
					bytes[num4++] = 15;
				}
				bytes[num4++] = (byte)c;
			}
			if (b == 14 && num4 < num3)
			{
				b = 15;
				bytes[num4++] = 15;
			}
			byteCount = num4 - byteOffset;
			return i - num;
		}
	}
}
